package com.poi.demopoi.utils;

import com.poi.demopoi.exception.rtest.R3;
import com.poi.demopoi.exception.rtest.ResultStatus;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import org.springframework.http.HttpStatus;

import java.io.Serializable;

/**
 * https://blog.csdn.net/qq_34347620/article/details/102239179 ： Spring Boot 无侵入式 实现API接口统一JSON格式返回
 * 描述：正规军的 API接口统一JSON格式
 * 拓展：
 * https://www.jianshu.com/p/90bac4eda34a ： 如何优雅设计 API 接口，实现统一格式返回？
 * https://www.toutiao.com/i6694404645827117572/ 如何设计API接口，实现统一格式返回？  (很多不错的技术连接博文)
 * 探究： R3.java
 */
@Setter
@Getter
@ToString
@Accessors(chain = true)
public class R<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private int code = 200;
    private String msg;
    private T data;

    /** 业务成功返回业务代码和描述信息 */
    public static R<Void> ok() {
        return rBuilder().code(200).msg("操作成功").build();
    }

    /** 业务成功返回业务代码,描述和返回的参数 */
    public static <T> R<T> ok(T data) {
        return rBuilder().code(200).msg("操作成功").data(data).build();
    }


//    public static R ok() {
//        return rBuilder().code(200).msg("操作成功").build();
//    }

//    public static R ok(Object data) {
//        return rBuilder().code(200).msg("操作成功").data(data).build();
//    }



    /** 业务异常返回业务代码和描述信息 */
    public static <T> R<T> error() {
        return rBuilder().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).msg("未知异常，请联系管理员").build();
//        return new R<T>(ResultStatus.INTERNAL_SERVER_ERROR, null);
    }
//    public static R error() {
//        return rBuilder().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).msg("未知异常，请联系管理员").build();
////        return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), "未知异常，请联系管理员");
//    }

    public static R error(String msg) {
        return rBuilder().code(HttpStatus.INTERNAL_SERVER_ERROR.value()).msg(msg).build();
//        return error(HttpStatus.INTERNAL_SERVER_ERROR.value(), msg);
    }

    /** 业务异常返回业务代码,描述和返回的参数 */
    public static <T> R<T>  error(int code, String msg) {
        return rBuilder().code(code).msg(msg).build();
    }



    public R() {
    }

    public R(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    //此种构建R的方式也不错： https://www.cnblogs.com/xiaobai1202/p/10907576.html
    public static <T> RBuilder rBuilder() {
        return new RBuilder<T>();
    }

    //内部类 用来解决static 不能使用泛型的问题
    private static class RBuilder<T> {
        private int code;
        private String msg;
        private T data;

        //构建一个AppResponse 对象
        public R build() {
            return new R<T>(this.code, this.msg, this.data);
        }

        public RBuilder code(int status) {
            this.code = status;
            return this;
        }

        public RBuilder msg(String msg) {
            this.msg = msg;
            return this;
        }

        public RBuilder data(T data) {
            this.data = data;
            return this;
        }
    }
}
